#include "EEG1042.h"

BEGIN_EVENT_TABLE(EEG1042,wxEvtHandler)
EVT_SOCKET(BTSOCKET_ID, EEG1042::OnSocketEvent)
END_EVENT_TABLE()

EEG1042::EEG1042(void)
{
	wxTextFile	File;
	Instrument::Instrument();
	wxString Temp;
	
	MyName = _("EEG1042");
	
	SetElectrodes=0;

	if(File.Open(_T("./ConfigDevices/10_20System.txt")))
	{
		File.GoToLine(0);
		while (!File.Eof())
		{
			Temp = File.GetNextLine();
			if (!Temp.Contains(wxT("//")))
			{
				Electrodes[SetElectrodes] = Temp;
				SetElectrodes++;
			}
		}
		File.Close();
	}
	
	BrainBox = new NetworkProtocol();
}

EEG1042::~EEG1042(void)
{
	delete m_sock;
	delete BrainBox;
}

void *EEG1042::Entry(void)
{
	SampleStruct	Signal;
	memset(&Signal,0,sizeof(Signal));
	Signal.Data.DataLen	=	nChannels;

	Esci = false;
	while (!Esci)
	{
		if (IsRunning)
			{
			m_sock->Read(&BrainBox->VHeader,sizeof(BrainBox->VHeader));
			if ((strcmp(BrainBox->VHeader.String,"c1")==0) || (strcmp(BrainBox->VHeader.String,"c2")==0) )
			{ //RETURN START/STOP FRAME
				if (ControlFrame()!=0)
					StopDevice();
			}
			else if (strcmp(BrainBox->VHeader.String,"c3")==0)  //RETURN CONFIG FRAME
			{
				if (ControlFrame()!=0)	
					StopDevice();
			}
			else if (strcmp(BrainBox->VHeader.String,"c4")==0)	//RETURN CONTROL FRAME
			{
				if (ControlFrame()!=0)	
					StopDevice();
			}
			else if (strcmp(BrainBox->VHeader.String,"c4")==0)	//RETURN EXTENDED CONTROL FRAME
			{
				if (ControlFrame()!=0)	
					StopDevice();
			}
			else if (strcmp(BrainBox->VHeader.String,"d1")==0)	//DATA FRAME
			{
				if (ControlFrame()!=0)	
					StopDevice();
				else
				{
					if (IsRunning)
					{
						m_sock->Read(&BrainBox->VDataFrame32,sizeof(BrainBox->VDataFrame32));
						for (int i=0; i<32; i++)
						Signal.Data.Signal[i] = BrainBox->VDataFrame32.Data[i];
						PutSample(&Signal);
					}
				}

			}

			else if (strcmp(BrainBox->VHeader.String,"d2")==0);	//DATA DIGIOUT
			else if (strcmp(BrainBox->VHeader.String,"d3")==0);	//REQUEST DIGIIN
		}
	}
	Sleep(100);
	return NULL;
}

int EEG1042::OpenPort(const char* hostname, const char *nBrainBox, const char *SampleRate)
{
	//Open Socket Connection
	wxIPV4address addr;
	addr.Hostname(wxString::FromAscii(hostname));
	addr.Service(PORT_NUMBER);

	Resolution = 0.178; 
	nDevices = atoi(nBrainBox);
	nChannels = nDevices * 42; 
	SampleFreq = atoi(SampleRate);

	nChannels += 32+8+1;
	for (int j=0;j<32;j++)
	{
		Labels[j] = Electrodes[j];
		Maximum[j] = 5*1e3;				//in uV
		Minimum[j] = -5*1e3;
	}
	for (int j=32; j<(32+8); j++)
	{
		Labels[j] = wxString::Format(wxT("Digital%d"),j-31);
		Maximum[j] = 1;				
		Minimum[j] = 0;
	}
	Labels[32+8] = wxT("SpO2");
	Maximum[40] = 5*1e3;				//in uV
	Minimum[40] = -5*1e3;

	// Create the socket
	m_sock = new wxSocketClient();

	// Setup the event handler and subscribe to most events (Input, Connection, Lost Connection)
	m_sock->SetEventHandler(*this, BTSOCKET_ID);
	m_sock->SetNotify(wxSOCKET_CONNECTION_FLAG |
                    wxSOCKET_INPUT_FLAG |
                    wxSOCKET_LOST_FLAG);
    m_sock->Notify(true);
	
	

	bool ret;
	m_sock->Connect(addr,false);
	ret = m_sock->WaitOnConnect(10);
	
	if (ret)
	{
		//Connection ok
		if (m_sock->IsConnected())
		{
			SetMessage(wxString::Format(_("Connection to BrainBox OK")));	
			BrainBox->SetConfigFrame(SampleFreq);
			BrainBox->AddDevices(_T("EEG-1042"),nDevices);
			SendFrame((CastFrame *)&BrainBox->VConfigFrame);
			return 1;
		}
		else
		{
			SetMessage(wxString::Format(_("BrainBox SOCKET CONNECTION ERROR")));	
			return 0;
		}
	}
	else
	{
		SetMessage(wxString::Format(_("BrainBox SOCKET CONNECTION ERROR")));	
		return -1;
	}
		
	Initialize(nChannels,SampleFreq,20);
}

void EEG1042::StartDevice(wxString FileName,wxString FilePath,bool File)
{
	Instrument::StartDevice(FileName,FilePath,File);
	//Send Operative mode
	
	//SendStart
	BrainBox->SetEEGMode();
	SendFrame((CastFrame *)&BrainBox->VControlFrame);
	BrainBox->SetStartFrame();
	SendFrame((CastFrame *)&BrainBox->VRequestFrame);
	IsRunning = true;
}

void EEG1042::StopDevice()
{
	if (IsRunning)
	{
		BrainBox->SetStopFrame();
		SendFrame((CastFrame *)&BrainBox->VRequestFrame);
	}
	IsRunning=false;
	Esci = true;
	Instrument::StopDevice();
}

void EEG1042::SendFrame(CastFrame *Frame)
{
	int size = sizeof(CastFrame);
	m_sock->Write(Frame,size);
}

void EEG1042::OnSocketEvent(wxSocketEvent& event)
{
	/*SampleStruct	Signal;
	memset(&Signal,0,sizeof(Signal));
	Signal.Data.DataLen	=	nChannels;*/

	//Here are the socket Event
	switch (event.GetSocketEvent())
	{
	case wxSOCKET_INPUT:
		break;
	case wxSOCKET_CONNECTION:
		SetMessage(wxString::Format(_("Connection to BrainBox OK")));	
		break;
	case wxSOCKET_LOST:
		break;
	default:
		SetMessage(wxString::Format(_("Unexpected event")));	
		break;
	}
}

int EEG1042::ControlFrame(void)
{
	int ret;
	wxString msg;
	msg = wxT("");
	if (BrainBox->VHeader.Byte3>>7)
	{
		msg.Append(wxT("Frame Refused\n"));
		ret = 1;
	}
	else
		ret = 0;
	if ((BrainBox->VHeader.Byte3>>6)&&0x01)
	{
		ret = 2;
		msg.Append(wxT("No device responding \n"));
	}
	else
		ret = 0;
	if ((BrainBox->VHeader.Byte3>>5)&&0x01)
	{
		msg.Append(wxT("Configuration error in the Frame\n"));
		ret = 3;
	}
	else
		ret = 0;
	if (msg.Cmp(wxT(""))!=0)
		SetMessage(msg);
	return ret;
}